package com.opengltest;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Square {
	// Our vertices.
	protected float vertices[] = {
		      -1.0f,  1.0f, 0.0f,  // 0, Top Left
		      -1.0f, -1.0f, 0.0f,  // 1, Bottom Left
		       1.0f, -1.0f, 0.0f,  // 2, Bottom Right
		       1.0f,  1.0f, 0.0f,  // 3, Top Right
		};

	// The order we like to connect them.
	protected short[] indices = { 0, 1, 2, 0, 2, 3 };

	// Our vertex buffer.
	protected FloatBuffer vertexBuffer;

	// Our index buffer.
	protected ShortBuffer indexBuffer;

	public Square() {
		/**
		  *  为了提高性能，通常将这些数组存放到java.io 中定义的Buffer类中：
		  */
		// a float is 4 bytes, therefore we 
		// multiply the number if
		// vertices with 4.
		ByteBuffer vbb 
		  = ByteBuffer.allocateDirect(vertices.length * 4);
		vbb.order(ByteOrder.nativeOrder());
		vertexBuffer = vbb.asFloatBuffer();
		vertexBuffer.put(vertices);
		vertexBuffer.position(0);

		// short is 2 bytes, therefore we multiply 
		//the number if
		// vertices with 2.
		ByteBuffer ibb 
		 = ByteBuffer.allocateDirect(indices.length * 2);
		ibb.order(ByteOrder.nativeOrder());
		indexBuffer = ibb.asShortBuffer();
		indexBuffer.put(indices);
		indexBuffer.position(0);
	}

	/**
	 * This function draws our square on screen.
	 * @param gl
	 */
	public void draw(GL10 gl) {
		 //设置逆时针方法为面的“前面”
		gl.glFrontFace(GL10.GL_CCW); 
		// 打开 忽略“面”设置：
		gl.glEnable(GL10.GL_CULL_FACE); 
		//忽略背面
		gl.glCullFace(GL10.GL_BACK); 

		
		 /**
		 * 有了顶点的定义，下面一步就是如何将它们传给OpenGL ES库，
		 * OpenGL ES提供一个成为”管道Pipeline”的机制，
		 * 这个管道定义了一些“开关”来控制OpenGL ES支持的某些功能，缺省情况这些功能是关闭的，
		 * 如果需要使用OpenGL ES的这些功能，需要明确告知OpenGL “管道”打开所需功能。
		 * 因此对于我们的这个示例，需要告诉OpenGL库打开 Vertex buffer以便传入顶点坐标Buffer。
		 * 要注意的使用完某个功能之后，要关闭这个功能以免影响后续操作：
		 */
		// Enabled the vertices buffer for writing 
		//and to be used during
		// rendering.
		//启用VERTEX_ARRAY,可传入buffer
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		// Specifies the location and data format of 
		//an array of vertex
		// coordinates to use when rendering.
		//定义一个顶点坐标矩阵。
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, 
                                 vertexBuffer);

		
		/**
		 * 我们已定义好了多边形，下面就要了解如和使用OpenGL ES的API来绘制（渲染）这个多边形了。OpenGL ES提供了两类方法来绘制一个空间几何图形：
			public abstract void glDrawArrays(int mode, int first, int count)  
			 使用VetexBuffer 来绘制，顶点的顺序由vertexBuffer中的顺序指定。
			public abstract void glDrawElements(int mode, int count, int type, Buffer indices)
			可以重新定义顶点的顺序，顶点的顺序由indices Buffer 指定。
			
			
			同样的顶点，可以定义的几何图形可以有所不同，比如三个顶点，可以代表三个独立的点，也可以表示一个三角形，
			这就需要使用mode 来指明所需绘制的几何图形的基本类型。
			GL_POINTS: 绘制独立的点
			GL_LINE_STRIP: 绘制一系列线段
			GL_LINE_LOOP: 类同上，但是首尾相连，构成一个封闭曲线。
			GL_LINES : 顶点两两连接，为多条线段构成
			GL_TRIANGLES: 每隔三个顶点构成一个三角形，为多个三角形组成
			GL_TRIANGLE_STRIP : 每相邻三个顶点组成一个三角形，为一系列相接三角形构成
			GL_TRIANGLE_FAN: 以一个点为三角形公共顶点，组成一系列相邻的三角形
		 */
		//绘制顶点
		gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
				  GL10.GL_UNSIGNED_SHORT, indexBuffer);

		// Disable the vertices buffer.
		//关闭buff输入
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
		// Disable face culling.
		// 关闭面
		gl.glDisable(GL10.GL_CULL_FACE); 
	}

}
